package com.web.exiaodao.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.PayReqBatchTransData;
import com.alipay.PayService;
import com.alipay.config.AlipayConfig;
import com.google.common.base.Function;
import com.web.exiaodao.business.constant.JConstant;
import com.web.exiaodao.business.entity.User;
import com.web.exiaodao.business.entity.WalletWithdrawRecord;
import com.web.exiaodao.business.repository.UserRepository;
import com.web.exiaodao.business.repository.WalletWithdrawRecordRepository;
import com.web.exiaodao.business.service.WalletWithdrawRecordService;
import com.web.exiaodao.remote.vo.WalletWithdrawRecordVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.DateUtils;
import com.web.webstart.base.util.Identities;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.DynamicSpecifications;
import com.web.webstart.base.util.jpa.MyPage;
import com.web.webstart.base.util.jpa.SearchFilter;
import com.web.webstart.base.util.jpa.SearchFilter.Operator;
import com.web.webstart.base.util.result.XaResult;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static com.web.exiaodao.business.constant.JConstant.SERVER_ADDRESS;
import static com.web.exiaodao.business.constant.JConstant.SERVER_NAME;
import static com.web.webstart.base.util.DateUtils.YYYYMMDDline;

@Service("WalletWithdrawRecordService")
@Transactional(readOnly = false)
public class WalletWithdrawRecordServiceImpl extends BaseService<WalletWithdrawRecordVo> implements WalletWithdrawRecordService {

    private static final Logger LOGGER = Logger.getLogger(WalletWithdrawRecordServiceImpl.class);

    @Autowired
    private WalletWithdrawRecordRepository walletWithdrawRecordRepository;

    @Autowired
    private UserRepository userRepository;

    /**
     * 查询单条WalletWithdrawRecord信息
     * //@param tId
     *
     * @return 返回单个WalletWithdrawRecord对象
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<WalletWithdrawRecordVo> findOne(Long modelId) throws BusinessException {
        WalletWithdrawRecord obj = new WalletWithdrawRecord();
        if (modelId != 0) {
            obj = walletWithdrawRecordRepository.findByIdAndStatusNot(modelId, XaConstant.Status.delete);
        }
        XaResult<WalletWithdrawRecordVo> xr = new XaResult<>();
        if (XaUtil.isNotEmpty(obj)) {
            xr.setObject(JSON.parseObject(JSON.toJSONString(obj), WalletWithdrawRecordVo.class));
            LOGGER.info("后台----->查询单个实体----->WalletWithdrawRecord");
        } else {
            xr.error(XaConstant.Message.object_not_find);
            LOGGER.info(XaConstant.Message.object_not_find);
        }
        return xr;
    }

    /**
     * 分页查询状态非status的WalletWithdrawRecord数据
     *
     * @param status
     * @param filterParams
     * @param pageable
     * @return 返回对象WalletWithdrawRecord集合
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<Page<WalletWithdrawRecordVo>> findListNEStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
        Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
        if (status == null) {// 默认显示非删除的所有数据
            status = XaConstant.Status.delete;
        }
        filters.put("status", new SearchFilter("status", Operator.NE, status));
        Page<WalletWithdrawRecord> page = walletWithdrawRecordRepository.findAll(DynamicSpecifications
                .bySearchFilter(filters.values(), WalletWithdrawRecord.class), pageable);
        XaResult<Page<WalletWithdrawRecordVo>> xr = new XaResult<>();
        xr.setObject(new MyPage<>(page, JSON.parseArray(JSON.toJSONString(page.getContent()), WalletWithdrawRecordVo.class)));

        //查询用户信息
        if (page.getContent().size() > 0) {
            List<Long> userIdLongs = com.web.webstart.base.util.CollectionUtils.subCollection(page.getContent(), "userId");
            Iterable<User> userIterable = userRepository.findAll(userIdLongs);
            Map<Long, User> userMap = com.web.webstart.base.util.CollectionUtils.listToMap(userIterable.iterator(), new Function<User, Long>() {
                @Override
                public Long apply(User user) {
                    return user.getId();
                }
            });
            for (int i = 0; i < xr.getObject().getContent().size(); ++i) {
                WalletWithdrawRecordVo vo = xr.getObject().getContent().get(i);
                User userTemp = userMap.get(vo.getUserId());
                xr.getObject().getContent().get(i).setUser(userTemp);
            }
        }

        LOGGER.info("后台----->分页查询实体集合（状态不等于）----->WalletWithdrawRecord");
        return xr;
    }

    /**
     * 分页查询状态status的WalletWithdrawRecord数据
     *
     * @param status
     * @param filterParams
     * @param pageable
     * @return 返回对象WalletWithdrawRecord集合
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<Page<WalletWithdrawRecordVo>> findListEQStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
        Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
        if (status == null) {// 默认显示正常数据
            status = XaConstant.Status.valid;
        }
        filters.put("status", new SearchFilter("status", Operator.EQ, status));
        Page<WalletWithdrawRecord> page = walletWithdrawRecordRepository.findAll(DynamicSpecifications
                .bySearchFilter(filters.values(), WalletWithdrawRecord.class), pageable);
        XaResult<Page<WalletWithdrawRecordVo>> xr = new XaResult<>();
        xr.setObject(new MyPage<>(page, JSON.parseArray(JSON.toJSONString(page.getContent()), WalletWithdrawRecordVo.class)));
        LOGGER.info("后台----->分页查询实体集合（状态等于）----->WalletWithdrawRecord");
        return xr;
    }


    /**
     * 保存WalletWithdrawRecord信息
     *
     * @param model
     * @return
     * @throws BusinessException
     */
    @Transactional(rollbackFor = Exception.class)
    public XaResult<WalletWithdrawRecordVo> saveOrUpdate(WalletWithdrawRecordVo model) throws BusinessException {
        WalletWithdrawRecord obj = null;
        if (XaUtil.isNotEmpty(model.getId())) {
            obj = walletWithdrawRecordRepository.findOne(model.getId());
        } else {
            obj = new WalletWithdrawRecord();
        }
        obj.setCreateUser(XaUtil.isNotEmpty(model.getCreateUser()) ? model.getCreateUser() : obj.getCreateUser());
        obj.setUserId(XaUtil.isNotEmpty(model.getUserId()) ? model.getUserId() : obj.getUserId());
        obj.setWithdrawMoney(XaUtil.isNotEmpty(model.getWithdrawMoney()) ? model.getWithdrawMoney() : obj.getWithdrawMoney());
        obj.setAipayAccount(XaUtil.isNotEmpty(model.getAipayAccount()) ? model.getAipayAccount() : obj.getAipayAccount());
        obj.setWithdrawStatus(XaUtil.isNotEmpty(model.getWithdrawStatus()) ? model.getWithdrawStatus() : obj.getWithdrawStatus());
        obj.setWithdrawSucessTime(XaUtil.isNotEmpty(model.getWithdrawSucessTime()) ? model.getWithdrawSucessTime() : obj.getWithdrawSucessTime());
        obj.setWithdrawTradeNo(XaUtil.isNotEmpty(model.getWithdrawTradeNo()) ? model.getWithdrawTradeNo() : obj.getWithdrawTradeNo());
        obj.setAlipayUsername(XaUtil.isNotEmpty(model.getAlipayUsername()) ? model.getAlipayUsername() : obj.getAlipayUsername());
        obj.setRemark(XaUtil.isNotEmpty(model.getRemark()) ? model.getRemark() : obj.getRemark());
        obj = walletWithdrawRecordRepository.save(obj);
        XaResult<WalletWithdrawRecordVo> xr = new XaResult<>();
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), WalletWithdrawRecordVo.class));
        LOGGER.info("后台新增或编辑数据成功！");
        return xr;
    }

    /**
     * 修改WalletWithdrawRecord状态，可一次修改多条   3删除  -1锁定  1正常
     * //@param userId
     *
     * @param modelIds
     * @param status
     * @return 返回WalletWithdrawRecord对象
     * @throws BusinessException
     */
    @Transactional(rollbackFor = Exception.class)
    public XaResult<WalletWithdrawRecordVo> multiOperate(
            String modelIds, Integer status) throws BusinessException {
        XaResult<WalletWithdrawRecordVo> xr = new XaResult<>();
        if (status == null) {
            status = XaConstant.Status.delete;
        }
        if (modelIds != null) {
            String[] ids = modelIds.split(",");
            for (String id : ids) {
                WalletWithdrawRecord obj = walletWithdrawRecordRepository.findByIdAndStatusNot(Long.parseLong(id), status);
                if (XaUtil.isNotEmpty(obj)) {
                    obj.setStatus(status);
                    obj = walletWithdrawRecordRepository.save(obj);
                }
            }
        }
        LOGGER.info("批量修改数据状态成功！");
        return xr;
    }

    //批量提现
    @Override
    public XaResult<String> withdrawOnAlipay(String modelIds , HttpServletRequest request) throws BusinessException {
        XaResult<String> xr = new XaResult<>();
        try {
            LOGGER.info("支付宝批量提现开始！");


            PayReqBatchTransData batchData = new PayReqBatchTransData();
            //通知地址
            String notify_url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/" + SERVER_NAME + "/api/alipay/notifyWithdraw";
            notify_url = JConstant.ENV == 1 ? notify_url : SERVER_ADDRESS + SERVER_NAME + "/api/alipay/notifyWithdraw";
            batchData.setNotify_url(notify_url);
            System.out.println(notify_url);

            batchData.setPay_date(DateUtils.getToday(YYYYMMDDline));//YYYYMMDD


            batchData.setBatch_no(DateUtils.getTodayStrSimple() + Identities.getRandomNumber(5));
            batchData.setBatch_num(modelIds.split(",").length+"");//付款总笔数;批量付款笔数（最少1笔，最多1000笔）。;1000

            String[] ids = modelIds.split(",");
            Double batchFee = 0.00;
            //付款详细数据
            String detail_data = "";
            //格式为：流水号1^收款方账号1^收款账号姓名1^付款金额1^备注说明1|流水号2^收款方账号2^收款账号姓名2^付款金额2^备注说明2。
            for(int i = 0; i < ids.length; ++i){
                WalletWithdrawRecord obj = walletWithdrawRecordRepository.findByIdAndStatusNot(XaUtil.getNutNullLong(ids[i],0l), XaConstant.Status.delete);
                if (obj == null) {
                    xr.error("提现申请不存在("+ids[i]+")");
                    return xr;
                }
                if (JConstant.WalletWithdrawStatus.WITHDRAW_ING.intValue() != obj.getWithdrawStatus()) {
                    xr.error("只有提现申请中的才能进行提现操作id=("+ids[i]+")");
                    return xr;
                }
                BigDecimal b1 = BigDecimal.valueOf(batchFee);
                BigDecimal b2 = BigDecimal.valueOf(obj.getWithdrawMoney());
                batchFee = b1.add(b2).doubleValue() ;

                detail_data = obj.getWithdrawTradeNo() + "^" +
                        (obj.getAipayAccount())  + "^" +
                        (obj.getAlipayUsername())  + "^" +
                        (obj.getWithdrawMoney())  + "^" +
                        (AlipayConfig.account_name+"*"+AlipayConfig.APPID+"*转账给"+"*" +obj.getAipayAccount()+"*"+obj.getAlipayUsername()) +
                        (i != ids.length-1?"|":"");
            }
            //总金额
            batchData.setBatch_fee(batchFee+"");//付款总金额;格式：10.01，精确到分。
            ////付款详细数据;付款的详细数据，最多支持1000笔。;
            batchData.setDetail_data(detail_data);

            String payHtmls = PayService.batchTransService(batchData);
            xr.success(payHtmls);
        } catch (Exception e) {
            xr.error("提现错误！");
            LOGGER.info("支付宝批量提现处理失败！");
            LOGGER.error(e.getMessage(), e);
        }
        return xr;
    }
}
